package com.badshun.player;

import com.badlogic.gdx.math.*;
import com.badlogic.gdx.graphics.*;
import com.badshun.box2d.*;
import com.badlogic.gdx.graphics.g2d.*;
import com.badlogic.gdx.*;
import com.badlogic.gdx.physics.box2d.*;
import java.util.*;
import com.badlogic.gdx.utils.*;

public class Enemy {
	public String name;
	private Vector2 position;
	private Texture image;
	private Box2DWorld world;
	private MainPlayer player;
	private OrthographicCamera camera;
	
	private Animation leftAnimation;
	private Animation rightAnimation;
	private Animation upAnimation;
	private Animation downAnimation;
	
	private TextureRegion keyFrame;
	
	public ACTION action;
	public DIRECTION direction;
	public IDLE idle;
	
	private float width;
	private float height;
	
	private float time;
	
	private SpriteBatch batch;
	
	public Body enemyBody;
	
	private float randomDistance;
	private int randomDirection;
	
	private final int UP = 0;
	private final int DOWN = 1;
	private final int LEFT = 2;
	private final int RIGHT = 3;
	private final int ALL = 4;
	
	private final int XZ = 0;
	private final int XF = 1;
	private final int YZ = 0;
	private final int YF = 1;
	
	public boolean isHitPlayer;
	
	public int HP = 5;
	
	public boolean isHitSkill;
	
	public boolean isDeath;
	
	public Enemy(String name,Vector2 position,Texture image,Box2DWorld world,MainPlayer player,OrthographicCamera camera) {
		this.name = name;
		this.position = position;
		this.image = image;
		this.world = world;
		this.player = player;
		this.camera = camera;
		
		batch = new SpriteBatch();
		
		defineEnemy();
	}
	
	private void defineEnemy() {
		TextureRegion[][] playerTextureRegionList = TextureRegion.split(image,image.getWidth() / 4,image.getHeight() / 4);

		leftAnimation = new Animation(0.08f,playerTextureRegionList[1]);
		rightAnimation = new Animation(0.08f,playerTextureRegionList[2]);
		upAnimation = new Animation(0.08f,playerTextureRegionList[3]);
		downAnimation = new Animation(0.08f,playerTextureRegionList[0]);

		leftAnimation.setPlayMode(Animation.PlayMode.LOOP);
		rightAnimation.setPlayMode(Animation.PlayMode.LOOP);
		upAnimation.setPlayMode(Animation.PlayMode.LOOP);
		downAnimation.setPlayMode(Animation.PlayMode.LOOP);
		
		action = ACTION.IDLE;
		direction = DIRECTION.DOWN;
		idle = IDLE.IDLE_DOWN;
		
		width = downAnimation.getKeyFrames()[0].getRegionWidth();
		height = downAnimation.getKeyFrames()[0].getRegionHeight();
		
		position = new Vector2(position.x + width / 2,position.y + height / 2);

		Texture texture = new Texture(Gdx.files.internal("player/main_player.jpg"));

		width = texture.getWidth() / 4;
		height = texture.getHeight() / 4;

		BodyDef bdef = new BodyDef();
		bdef.position.set(position.x + width / 2,position.y + height / 2);
		bdef.type = BodyDef.BodyType.DynamicBody;

		enemyBody = world.world.createBody(bdef);

		CircleShape circle = new CircleShape();
		
		circle.setRadius(30);

		FixtureDef fdef = new FixtureDef();
		fdef.shape = circle;
		fdef.filter.categoryBits = 16;
		fdef.filter.maskBits = 2 | 4 | 8;

		enemyBody.createFixture(fdef).setUserData(name + "ENEMY");
		
		circle.setRadius(300);

		fdef.shape = circle;
		fdef.filter.categoryBits = 16;
		fdef.filter.maskBits = 2 | 4 | 8 | 32;
		fdef.isSensor = true;

		enemyBody.createFixture(fdef).setUserData(name + "CIRCLR_ENEMY");
	}
	
	private void goByDefault() {
		Random random = new Random();
		
		boolean ifRandom = true;
		
		if(ifRandom) {
			randomDirection = random.nextInt(5);
		}
		
		randomDistance = random.nextFloat() * 100;
		
		float distanceX = random.nextFloat() * 100;
		float distanceY = random.nextFloat() * 100;
		
		if(randomDirection == UP) {
			goVertical(randomDistance);
			
			int ifContinue = random.nextInt(2);
			
			ifRandom = ifContinue == 1;
		} else if(randomDirection == DOWN) {
			goVertical(-randomDistance);
			
			int ifContinue = random.nextInt(2);

			ifRandom = ifContinue == 1;
		} else if(randomDirection == LEFT) {
			goHorizontal(-randomDistance);
			
			int ifContinue = random.nextInt(2);

			ifRandom = ifContinue == 1;
		} else if(randomDirection == RIGHT) {
			goHorizontal(randomDistance);
			
			int ifContinue = random.nextInt(2);

			ifRandom = ifContinue == 1;
		} else if(randomDirection == ALL) {
			int x = random.nextInt(2);
			int y = random.nextInt(2);
			if(x == XZ) {
				if(y == YZ) {
					goAllDistance(distanceX,distanceY);
				} else if(y == YF) {
					goAllDistance(distanceX,-distanceY);
				}
			} else if(x == XF) {
				if(y == YZ) {
					goAllDistance(-distanceX,distanceY);
				} else if(y == YF) {
					goAllDistance(-distanceX,-distanceY);
				}
			}
			
			int ifContinue = random.nextInt(2);

			ifRandom = ifContinue == 1;
		}
	}
	
	private void seePlayer() {
		if(player.enemyName.equals(name)) {
			Vector2 mPosition = player.position;
			
			float distanceX = 0;
			float distanceY = 0;
			
			if(mPosition.x != position.x) {
				distanceX = mPosition.x - position.x;
				
				distanceX /= 100;
			}
			
			if(mPosition.y != position.y) {
				distanceY = mPosition.y - position.y;

				distanceY /= 100;
			}
			
			goAllDistance(distanceX,distanceY);
		}
	}
	
	private void goHorizontal(float distance) {
		enemyBody.setType(BodyDef.BodyType.DynamicBody);
		enemyBody.applyLinearImpulse(new Vector2(distance,0),enemyBody.getWorldCenter(),true);
		
		action = ACTION.MOVE;
	}
	
	private void goVertical(float distance) {
		enemyBody.setType(BodyDef.BodyType.DynamicBody);
		enemyBody.applyLinearImpulse(new Vector2(0,distance),enemyBody.getWorldCenter(),true);
		
		action = ACTION.MOVE;
	}
	
	private void goAllDistance(float distanceX,float distanceY) {
		enemyBody.setType(BodyDef.BodyType.DynamicBody);
		enemyBody.applyLinearImpulse(new Vector2(distanceX,distanceY),enemyBody.getWorldCenter(),true);
		
		action = ACTION.MOVE;
	}
	
	
	private void stop() {
		enemyBody.applyLinearImpulse(new Vector2(-enemyBody.getLinearVelocity().x,-enemyBody.getLinearVelocity().y),enemyBody.getWorldCenter(),true);
		enemyBody.setType(BodyDef.BodyType.StaticBody);
		
		action = ACTION.IDLE;
	}
	
	private void checkDirection() {
		if(enemyBody.getLinearVelocity().x == 0 && enemyBody.getLinearVelocity().y == 0) action = ACTION.IDLE;
		if(enemyBody.getLinearVelocity().x < 0 && enemyBody.getLinearVelocity().y == 0) direction = DIRECTION.LEFT;
		if(enemyBody.getLinearVelocity().x > 0 && enemyBody.getLinearVelocity().y == 0f) direction = DIRECTION.RIGHT;
		if(enemyBody.getLinearVelocity().x == 0 && enemyBody.getLinearVelocity().y > 0) direction = DIRECTION.UP;
		if(enemyBody.getLinearVelocity().x == 0 && enemyBody.getLinearVelocity().y < 0) direction = DIRECTION.DOWN;
		
		if(enemyBody.getLinearVelocity().x >= enemyBody.getLinearVelocity().y) {
			
		}
	}
	
	public TextureRegion getKeyFrame(float time) {
		if(direction == DIRECTION.LEFT && action == ACTION.MOVE) return leftAnimation.getKeyFrame(time);
		else if(direction == DIRECTION.RIGHT && action == ACTION.MOVE) return rightAnimation.getKeyFrame(time);
		else if(direction == DIRECTION.UP && action == ACTION.MOVE) return upAnimation.getKeyFrame(time);
		else if(direction == DIRECTION.DOWN && action == ACTION.MOVE) return downAnimation.getKeyFrame(time);
		else if(action == ACTION.IDLE) {
			if(idle == IDLE.IDLE_LEFT) return leftAnimation.getKeyFrames()[0];
			else if(idle == IDLE.IDLE_RIGHT) return rightAnimation.getKeyFrames()[0];
			else if(idle == IDLE.IDLE_UP) return upAnimation.getKeyFrames()[0];
			else if(idle == IDLE.IDLE_DOWN) return downAnimation.getKeyFrames()[0];
		}

		return null;
	}
	
	public void destroy() {
		Array<Body> bodyList = new Array<Body>();

		world.world.getBodies(bodyList);

		for(int i = 0; i < bodyList.size; i++) {
			if(bodyList.get(i).getUserData() != null) {
				if(bodyList.get(i).getUserData().equals(name)) {
					Array<Fixture> fixtureList = bodyList.get(i).getFixtureList();

					for(int j = 0; j < fixtureList.size; j++) {
						if(fixtureList.get(j).getUserData().toString().startsWith(name)) {
							bodyList.get(i).destroyFixture(fixtureList.get(j));
						}
					}

					world.world.destroyBody(bodyList.get(i));
				}
			}
		}
	}
	
	public void checkDeath() {
		if(HP == 0) {
			isDeath = true;
			destroy();
		}
	}
	
	public void render() {
		checkDirection();
		checkDeath();
		
		if(!player.enemyName.equals(name)) {
			goByDefault();
		}
		
		position.set(enemyBody.getPosition().x - width / 2,enemyBody.getPosition().y - height / 2);
		
		seePlayer();
		
		batch.setProjectionMatrix(camera.combined);
		batch.begin();
		
		keyFrame = getKeyFrame(time);
		
		batch.draw(keyFrame,position.x,position.y,width,height);
		batch.end();
		
		time += Gdx.graphics.getDeltaTime();
	}
	
	public enum ACTION {
		ATK,MOVE,IDLE
	}

	public enum DIRECTION {
		LEFT,RIGHT,UP,DOWN
	}

	public enum IDLE {
		IDLE_LEFT,IDLE_RIGHT,IDLE_UP,IDLE_DOWN
	}
}
